#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cjson/cJSON.h"

// 读取文件内容到字符串
char* read_file(const char *filename) {
  FILE *file = fopen(filename, "rb");
  if (!file) {
    perror("Failed to open file");
    return NULL;
  }

  fseek(file, 0, SEEK_END);
  long length = ftell(file);
  fseek(file, 0, SEEK_SET);

  char *buffer = (char*)malloc(length + 1);
  if (!buffer) {
    fclose(file);
    perror("Memory allocation failed");
    return NULL;
  }

  size_t read_len = fread(buffer, 1, length, file);
  if (read_len != length) {
    free(buffer);
    fclose(file);
    perror("Failed to read file");
    return NULL;
  }

  buffer[length] = '\0';
  fclose(file);
  return buffer;
}

// 递归打印JSON内容
void print_json(cJSON *item, int depth) {
  if (!item) return;

  if (item->string && strcmp(item->string, "raw_data") == 0 && cJSON_IsArray(item)) {
    printf("[...]\n");
    return; // 跳过grades数组
  }

  // 缩进
  for (int i = 0; i < depth; i++) printf("  ");

  // 根据类型处理
  if (cJSON_IsObject(item)) {
    printf("{\n");
    cJSON *child = item->child;
    while (child) {
      // 打印键
      for (int i = 0; i < depth + 1; i++) printf("  ");
      printf("\"%s\": ", child->string);

      // 递归打印值
      print_json(child, depth + 1);

      child = child->next;
      if (child) printf(",");
      printf("\n");
    }
    for (int i = 0; i < depth; i++) printf("  ");
    printf("}");
  } 
  else if (cJSON_IsArray(item)) {
    printf("[\n");
    cJSON *child = item->child;
    while (child) {
      print_json(child, depth + 1);
      child = child->next;
      if (child) printf(",");
      printf("\n");
    }
    for (int i = 0; i < depth; i++) printf("  ");
    printf("]");
  }
  else if (cJSON_IsString(item)) {
    printf("\"%s\"", item->valuestring);
  }
  else if (cJSON_IsNumber(item)) {
    // 判断是整数还是浮点数
    if (item->valuedouble == (double)item->valueint) {
      printf("%d", item->valueint);
    } else {
      printf("%f", item->valuedouble);
    }
  }
  else if (cJSON_IsBool(item)) {
    printf("%s", cJSON_IsTrue(item) ? "true" : "false");
  }
  else if (cJSON_IsNull(item)) {
    printf("null");
  }
}

int main(int argc, char *argv[]) {
  if (argc < 2) {
    printf("Usage: %s <json_file>\n", argv[0]);
    return EXIT_FAILURE;
  }

  char *json_string = read_file(argv[1]);
  if (!json_string) {
    return EXIT_FAILURE;
  }

  cJSON *json = cJSON_Parse(json_string);
  free(json_string);

  if (!json) {
    const char *error_ptr = cJSON_GetErrorPtr();
    if (error_ptr) {
      fprintf(stderr, "Error before: %s\n", error_ptr);
    }
    return EXIT_FAILURE;
  }

  printf("Parsed JSON content:\n");
  print_json(json, 0);
  printf("\n");

  cJSON_Delete(json);

  return EXIT_SUCCESS;
}
